from rest_framework import serializers
from django_redis import get_redis_connection
from redis import RedisError
import logging

# 日志记录器
logger = logging.getLogger('django')


class ImageCodeCheckSerializer(serializers.Serializer):
    """发送短信验证码前的图片验证码校验逻辑"""

    # 定义校验字段
    image_code_id = serializers.UUIDField()
    text = serializers.CharField(min_length=4,max_length=4)

    # 实现校验
    def validate(self, attrs):
        # 接受要校验的参数
        image_code_id = attrs['image_code_id']
        client_text = attrs['text']

        # 查询redis数据库，获取后端存储的图片验证码
        redis_conn = get_redis_connection('verify_codes')
        server_text = redis_conn.get('img_%s' % image_code_id)
        if server_text is None:
            # 后端的图片验证码不存在或者过期
            raise serializers.ValidationError('无效的图片验证码')

        # 获取完图片验证码后，删除图片验证码
        try:
            redis_conn.delete('img_%s' % image_code_id)
        except RedisError as e:
            logger.error(e)

        # 服务器验证码和客户端验证码对比
        server_text = server_text.decode() # 将bytes类型的server_text转字符串
        if server_text.lower() != client_text:
            raise serializers.ValidationError('输入图片验证码有误')

        # 检查是否在60s内有发送记录
        # 逻辑：
            # 每发送一条短信，在redis数据库中存储一条记录，生命周期是60秒
            # 再次发送短信以前，取出该条记录，如果存在就表示频繁发送短信。反之，可以继续发送短信
        mobile = self.context['view'].kwargs['mobile']
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        if send_flag:
            raise serializers.ValidationError('发送短信过于频繁')

        return attrs
